package com.wss.common.widget.dialog;

import butterknife.Unbinder;
import com.orhanobut.logger.Logger;
import com.wss.common.base.ResourceTable;
import com.wss.common.utils.PxUtils;
import com.wss.common.utils.ValidUtils;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.service.Window;
import ohos.app.Context;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;

public class AppDialog implements Component.ClickedListener {

    private static final int MAX_ITEM = 7;

    /**
     * 对话框的顶级父类
     */
    StackLayout dialogLayout;

    /**
     * 中间显示的Dialog 父View
     */
    DirectionalLayout llCenter;
    Text tvTitle;
    Text tvContent;
    TextField edtInput;

    Button btnLeft;
    Button btnRight;
    Component btnLine;

    /**
     * 中间弹出对话框的Content View
     */
    DirectionalLayout contentLayout;
    ScrollView centerScrollView;

    /**
     * 底部弹出的Dialog 父View
     */
    DirectionalLayout llBottom;
    DirectionalLayout llContext;
    ScrollView bottomScrollView;
    Text tvCancel;

    private CommonDialog dialog;
    private Unbinder butterKnifeBinder;
    private Builder builder;

    private AppDialog() {

    }

    private AppDialog(Builder builder) {
        this.builder = builder;
    }

    /**
     * 显示对话框
     */
    public void show() {
        initView();
        dialog.show();
    }

    public boolean isShowing() {
        return dialog != null && dialog.isShowing();
    }

    /**
     * 关闭对话框
     */
    public void dismiss() {
        if (dialog != null) {
            dialog.destroy();
        }
        if (butterKnifeBinder != null) {
            butterKnifeBinder.unbind();
        }
    }

    private void findView(Component view) {

        dialogLayout= (StackLayout) view.findComponentById(ResourceTable.Id_dialog_layout);
        llCenter= (DirectionalLayout) view.findComponentById(ResourceTable.Id_ll_center);

        tvTitle= (Text) view.findComponentById(ResourceTable.Id_tv_title);
        tvContent= (Text) view.findComponentById(ResourceTable.Id_tv_content);
        edtInput= (TextField) view.findComponentById(ResourceTable.Id_edt_input);
        btnLeft= (Button) view.findComponentById(ResourceTable.Id_btn_left);
        btnRight= (Button) view.findComponentById(ResourceTable.Id_btn_right);
        btnLine = view.findComponentById(ResourceTable.Id_btn_line);
        contentLayout= (DirectionalLayout) view.findComponentById(ResourceTable.Id_ll_content_layout);
        centerScrollView= (ScrollView) view.findComponentById(ResourceTable.Id_center_scroll_view);
        llBottom= (DirectionalLayout) view.findComponentById(ResourceTable.Id_ll_bottom);
        llContext= (DirectionalLayout) view.findComponentById(ResourceTable.Id_ll_context);
        bottomScrollView= (ScrollView) view.findComponentById(ResourceTable.Id_bottom_scroll_view);
        tvCancel= (Text) view.findComponentById(ResourceTable.Id_tv_cancel);

        dialogLayout.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (builder.canceledOnTouchOutside) {
                    dialog.hide();
                }
            }
        });
    }

    /**
     * 初始化View
     */
    private void initView() {

        Component dialogView = LayoutScatter.getInstance(builder.context)
                .parse(ResourceTable.Layout_dialog_app,
                        null,
                        false);

        //TODO 设置dialog style
        dialogView.setMinWidth(PxUtils.getScreenWidth(builder.context));
        dialog = new CommonDialog(builder.context);
        dialog.setSize(ComponentContainer.LayoutConfig.MATCH_CONTENT,
                ComponentContainer.LayoutConfig.MATCH_CONTENT);
        dialog.setContentCustomComponent(dialogView);
        dialog.setTransparent(true);

        findView(dialogView);

        btnLeft.setClickedListener(this);
        btnRight.setClickedListener(this);
        tvCancel.setClickedListener(this);


        Window window = dialog.getWindow();
        if (window != null) {
            //TODO 设置dialog的window
        }
        dialog.setSwipeToDismiss(builder.canceledOnTouchOutside);
        dialog.setDestroyedListener(builder.dialogDismissListener);
        switch (builder.type) {
            case DialogType.INPUT:
                //带文本框输入
                setInputSetting();
                break;
            case DialogType.NO_TITLE:
                tvTitle.setVisibility(Component.HIDE);
                setCommonSetting();
                break;
            case DialogType.BOTTOM_IN:
                //底部弹出对话框
                setBottomSetting();
                break;
            case DialogType.REPLACE_ALL:
                //替换全部View
                dialogLayout.removeAllComponents();
                dialogLayout.addComponent(builder.allDialogView);
                break;
            case DialogType.REPLACE_CONTENT:
                //替换Content View
                contentLayout.removeAllComponents();
                contentLayout.addComponent(builder.contentView);
                break;
            case DialogType.REPLACE_BOTTOM:
                //替换底部View
                llBottom.setVisibility(Component.VISIBLE);
                llBottom.removeAllComponents();
                llBottom.addComponent(builder.bottomView);
                break;
            case DialogType.DEFAULT:
                //默认对话框
            default:
                setCommonSetting();
                break;
        }
    }

    /**
     * 常规对话框相关设置
     */
    private void setCommonSetting() {
        llCenter.setVisibility(Component.VISIBLE);
        tvContent.setTextSize((int) builder.contentTextSize);
        btnLeft.setTextSize((int) builder.leftButtonTextSize);
        btnRight.setTextSize((int) builder.rightButtonTextSize);
        tvContent.setTextColor(new Color(builder.contentTextColor));
        btnLeft.setTextColor(new Color(builder.leftButtonTextColor));
        btnRight.setTextColor(new Color(builder.rightButtonTextColor));
        if (ValidUtils.isValid(builder.title)) {
            tvTitle.setText(builder.title);
        }
        if (ValidUtils.isValid(builder.letButtonText)) {
            btnLeft.setText(builder.letButtonText);
        }
        if (ValidUtils.isValid(builder.rightButtonText)) {
            btnRight.setText(builder.rightButtonText);
        }
        tvContent.setText(builder.content);
        //TODO centerScrollView.post暂未找到替代方案
//        centerScrollView.post(() -> {
//            int height = centerScrollView.getHeight();
//            int max = PxUtils.getScreenHeight(builder.context) * 3 / 5;
//            if (height > max) {
//                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) bottomScrollView.getLayoutParams();
//                params.height = max;
//                centerScrollView.setLayoutParams(params);
//            }
//        });

        if (builder.isSingleButton) {
            //单按钮
            btnLeft.setVisibility(Component.HIDE);
            btnLine.setVisibility(Component.HIDE);
            ShapeElement shapeElement = new ShapeElement(builder.context, ResourceTable.Graphic_corners_left_white_gray_empty_shape);
            btnRight.setBackground(shapeElement);
        }
    }

    /**
     * 文本框输入类型相关设置
     */
    private void setInputSetting() {
        setCommonSetting();
        edtInput.setVisibility(Component.VISIBLE);
        tvContent.setVisibility(Component.HIDE);
        if (dialog.getWindow() != null) {
            //TODO 设置软键盘
//            dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
        }
        edtInput.setTextSize((int) builder.inputTextSize);
        edtInput.setTextColor(builder.inputTextColor);
        edtInput.setHintColor(new Color(builder.inputHintTextColor));
        edtInput.setTextInputType(builder.inputType);
        if (builder.textWatcher != null) {
            edtInput.addTextObserver(builder.textWatcher);
        }
        if (ValidUtils.isValid(builder.inputHintText)) {
            edtInput.setHint(builder.inputHintText);
        }
        if (ValidUtils.isValid(builder.inputDefaultText)) {
            edtInput.setText(builder.inputDefaultText);
            //TODO set textField selection
//            edtInput.setSelection(builder.inputDefaultText.length());
        }
    }

    /**
     * 底部弹出类型相关设置
     */
    private void setBottomSetting() {
        llBottom.setVisibility(Component.VISIBLE);
        tvCancel.setTextSize((int) builder.bottomCancelTextSize);
        tvCancel.setTextColor(new Color(builder.bottomCancelTextColor));
        if (ValidUtils.isValid(builder.bottomTitleText)) {
            tvCancel.setText(builder.bottomCancelText);
        }
        int size = ValidUtils.isValid(builder.bottomItems) ? builder.bottomItems.size() : 0;
        setItemScrollViewHeight(size);
        llContext.removeAllComponents();
        for (int i = 0; i < size; i++) {
            Component v = LayoutScatter.getInstance(builder.context)
                    .parse(ResourceTable.Layout_layout_item_of_dialog_bottom_in, null, false);
            Text item = (Text) v.findComponentById(ResourceTable.Id_tv_text);
            item.setText(builder.bottomItems.get(i));
            item.setTag(i);
            item.setTextColor(new Color(builder.bottomItemTextColor));
            item.setTextSize((int) builder.bottomItemTextSize);
            item.setClickedListener(v1 -> {
                if (builder.itemClickListener != null) {
                    builder.itemClickListener.onItemClick((int) v1.getTag(), ((Text) v1).getText().toString());
                }
                dismiss();
            });
            llContext.addComponent(v);
        }
    }

//    @OnClick({ResourceTable.Id_btn_left, ResourceTable.Id_btn_right, ResourceTable.Id_tv_cancel})
    public void onClick(@NotNull Component v) {
        if (v.getId() == ResourceTable.Id_btn_left) {
            onButtonClick(builder.letButtonListener);
        } else if (v.getId() == ResourceTable.Id_btn_right) {
            onButtonClick(builder.rightButtonListener);
        } else if (v.getId() == ResourceTable.Id_tv_cancel) {
            dismiss();
        }
    }

    /**
     * 给点击事件设置数据
     *
     * @param listener listener
     */
    private void onButtonClick(OnButtonClickListener listener) {
        if (builder.type == DialogType.INPUT) {
            if (listener != null) {
                listener.onClick(edtInput.getText().toString().trim());
            }
            //TODO 隐藏键盘
//            KeyboardUtils.hideKeyboard(edtInput);
        } else {
            if (listener != null) {
                listener.onClick(tvContent.getText().toString());
            }
        }
        dismiss();
    }

    /**
     * 设置底部弹出带条目的ScrollView的高度
     *
     * @param size 条目数量
     */
    private void setItemScrollViewHeight(int size) {
        // 添加条目过多的时候控制高度
        if (size >= MAX_ITEM) {
            DirectionalLayout.LayoutConfig params = (DirectionalLayout.LayoutConfig) bottomScrollView.getLayoutConfig();
            params.height = PxUtils.getScreenHeight(builder.context) / 2;
            bottomScrollView.setLayoutConfig(params);
        }
    }

    /**
     * 相机的Item
     *
     * @param context context
     * @return List
     */
    @NotNull
    public static List<String> getPhotoItem(@NotNull Context context) {
        List<String> items = new ArrayList<>();
        items.add(context.getString(ResourceTable.String_camera));
        items.add(context.getString(ResourceTable.String_album));
        return items;
    }

    /**
     * Describe：对话框建造者
     * Created by 吴天强 on 2018年9月27日
     */
    public static class Builder {
        Context context;
        /**
         * 对话框类型
         */
        @DialogType.Type
        int type = DialogType.DEFAULT;

        /**
         * 文本框输入类型
         */
        int inputType = InputAttribute.PATTERN_TEXT;
        /**
         * 对话框Title
         */
        String title;
        /**
         * 显示内容文字颜色
         */
        int contentTextColor = Color.BLACK.getValue();
        /**
         * 显示内容文字大小
         */
        float contentTextSize = PxUtils.fp2px(16);
        /**
         * 对话框内容
         */
        String content;
        /**
         * 左按钮文字
         */
        String letButtonText;
        /**
         * 右按钮文字
         */
        String rightButtonText;
        /**
         * 左按钮事件
         */
        OnButtonClickListener letButtonListener;
        /**
         * 右按钮事件
         */
        OnButtonClickListener rightButtonListener;

        /**
         * 左按钮文字颜色
         */
        int leftButtonTextColor = Color.GRAY.getValue();
        /**
         * 右按钮文字颜色
         */
        int rightButtonTextColor = Color.getIntColor("#0099FF");
        /**
         * 左按钮文字大小
         */
        float leftButtonTextSize = PxUtils.fp2px(18);
        /**
         * 右按钮文字大小
         */
        float rightButtonTextSize = PxUtils.fp2px(18);

        /**
         * 底部弹出多条目内容
         */
        List<String> bottomItems;
        /**
         * 底部多条目点击事件
         */
        OnItemClickListener itemClickListener;
        /**
         * 底部弹出对话框标题文字
         */
        String bottomTitleText;
        /**
         * 底部弹出对话框取消按钮文字
         */
        String bottomCancelText;
        /**
         * 底部弹出对话框取消按钮文字颜色
         */
        int bottomCancelTextColor = Color.GRAY.getValue();
        /**
         * 底部弹出对话框Item文字颜色
         */
        int bottomItemTextColor = Color.BLACK.getValue();
        /**
         * 底部弹出对话框取消按钮文字大小
         */
        float bottomCancelTextSize = PxUtils.fp2px(18);
        /**
         * 底部弹出对话框Item文字大小
         */
        float bottomItemTextSize = PxUtils.fp2px(16);

        /**
         * 输入框默认文字
         */
        String inputDefaultText;
        /**
         * 输入框hint文字
         */
        String inputHintText;
        /**
         * 输入框文字颜色
         */
        Color inputTextColor = Color.BLACK;
        /**
         * 输入框Hint文字颜色
         */
        int inputHintTextColor = Color.GRAY.getValue();
        /**
         * 输入框文字大小
         */
        float inputTextSize = PxUtils.fp2px(16);
        /**
         * 输入框输入监听
         */
        Text.TextObserver textWatcher;
        /**
         * 替换整个Dialog内容的View
         */
        Component allDialogView;
        /**
         * 替换中间部分View
         */
        Component contentView;
        /**
         * 替换底部弹出View
         */
        Component bottomView;

        /**
         * 是否单按钮
         */
        boolean isSingleButton;

        /**
         * 是否可以取消
         */
        boolean cancelable = true;

        /**
         * 点击对话框周围是否可取消
         */
        boolean canceledOnTouchOutside = true;

        /**
         * 对话框消失监听
         */
        CommonDialog.DestroyedListener dialogDismissListener;

        /**
         * 初始化
         *
         * @param context 上下文
         */
        public Builder(Context context) {
            this.context = context;
        }

        /**
         * 设置对话框类型
         *
         * @param type DialogType
         * @return Builder
         */
        public Builder setDialogType(@DialogType.Type int type) {
            this.type = type;
            return this;
        }

        /**
         * 设置文本框输入类型
         *
         * @param inputType 输入类型
         * @return Builder
         */
        public Builder setInputType(int inputType) {
            this.inputType = inputType;
            return this;
        }

        /**
         * 设置对话框标题
         *
         * @param title 标题
         * @return Builder
         */
        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        /**
         * 设置对话框内容
         *
         * @param content 内容
         * @return Builder
         */
        public Builder setContent(String content) {
            this.content = content;
            return this;
        }

        /**
         * 设置显示内容文字颜色
         *
         * @param color 颜色
         * @return Builder
         */
        public Builder setContentTextColor(int color) {

            this.contentTextColor = color;
            return this;
        }

        /**
         * 设置显示内容文字大小
         *
         * @param contentTextSize 大小
         * @return Builder
         */
        public Builder setContentTextSize(float contentTextSize) {
            this.contentTextSize = PxUtils.fp2px(contentTextSize);
            return this;
        }
        ////////////////////////////////////////左按钮设置////////////////////////////////////////////

        /**
         * 设置左按钮
         *
         * @param text 显示文字
         * @return Builder
         */
        public Builder setLeftButton(String text) {
            return setLeftButton(text, null);
        }

        /**
         * 设置左按钮
         *
         * @param listener 监听事件
         * @return Builder
         */
        public Builder setLeftButton(OnButtonClickListener listener) {
            return setLeftButton(null, listener);
        }

        /**
         * 设置左按钮
         *
         * @param text     显示文字
         * @param listener 监听事件
         * @return Builder
         */
        public Builder setLeftButton(String text, OnButtonClickListener listener) {
            this.letButtonText = text;
            this.letButtonListener = listener;
            return this;
        }

        /**
         * 设置左按钮文字颜色
         *
         * @param color 颜色
         * @return Builder
         */
        public Builder setLeftButtonTextColor(int color) {

            this.leftButtonTextColor = color;
            return this;
        }

        /**
         * 设置左按钮文字大小
         *
         * @param size 大小
         * @return Builder
         */
        public Builder setLeftButtonTextSize(float size) {
            this.leftButtonTextSize = PxUtils.fp2px(size);
            return this;
        }

        ////////////////////////////////////////右按钮设置////////////////////////////////////////////

        /**
         * 设置右按钮
         *
         * @param text 显示文字
         * @return Builder
         */
        public Builder setRightButton(String text) {
            return setRightButton(text, null);
        }

        /**
         * 设置右按钮
         *
         * @param listener 监听事件
         * @return Builder
         */
        public Builder setRightButton(OnButtonClickListener listener) {
            return setRightButton(null, listener);
        }

        /**
         * 设置右按钮
         *
         * @param text     显示文字
         * @param listener 监听事件
         * @return Builder
         */
        public Builder setRightButton(String text, OnButtonClickListener listener) {
            this.rightButtonText = text;
            this.rightButtonListener = listener;
            return this;
        }

        /**
         * 设置右按钮文字颜色
         *
         * @param color 颜色
         * @return Builder
         */
        public Builder setRightButtonTextColor(int color) {

            this.rightButtonTextColor = color;
            return this;
        }

        /**
         * 设置右按钮文字大小
         *
         * @param size 大小
         * @return Builder
         */
        public Builder setRightButtonTextSize(float size) {
            this.rightButtonTextSize = PxUtils.fp2px(size);
            return this;
        }
        ////////////////////////////////////////单按钮设置////////////////////////////////////////////

        /**
         * 单按钮设置
         *
         * @param text 显示文字
         * @return Builder
         */
        public Builder setSingleButton(String text) {
            return setSingleButton(text, null);
        }

        /**
         * 单按钮设置
         *
         * @param listener 事件监听
         * @return Builder
         */
        public Builder setSingleButton(OnButtonClickListener listener) {
            return setSingleButton(null, listener);
        }

        /**
         * 单按钮设置
         *
         * @param text     显示文字
         * @param listener 事件监听
         * @return Builder
         */
        public Builder setSingleButton(String text, OnButtonClickListener listener) {
            this.isSingleButton = true;
            return setRightButton(text, listener);
        }

        /**
         * 设置单按钮文字颜色
         *
         * @param color 颜色
         * @return Builder
         */
        public Builder setSingleButtonTextColor(int color) {

            return setRightButtonTextColor(color);
        }

        /**
         * 设置单按钮文字大小
         *
         * @param size 大小
         * @return Builder
         */
        public Builder setSingleButtonTextSize(float size) {
            return setRightButtonTextSize(size);
        }

        ////////////////////////////////////////多条目设置////////////////////////////////////////////

        /**
         * 当type = 底部弹出的时候，设置弹出条目及监听
         *
         * @param items    弹出条目
         * @param listener 监听事件
         * @return Builder
         */
        public Builder setBottomItems(List<String> items, OnItemClickListener listener) {
            this.bottomItems = items;
            this.itemClickListener = listener;
            return this;
        }

        /**
         * 设置底部弹出对话框取消按钮文字
         *
         * @param text 显示文字
         * @return Builder
         */
        public Builder setBottomCancelText(String text) {
            this.bottomCancelText = text;
            return this;
        }

        /**
         * 设置底部弹出对话框标题文字
         *
         * @param text 显示文字
         * @return Builder
         */
        public Builder setBottomTitleText(String text) {
            this.bottomTitleText = text;
            return this;
        }

        /**
         * 设置底部弹出对话框取消按钮文字颜色
         *
         * @param color 颜色
         * @return Builder
         */
        public Builder setBottomCancelTextColor(int color) {

            this.bottomCancelTextColor = color;
            return this;
        }

        /**
         * 设置底部弹出对话框Item文字颜色
         *
         * @param color 颜色
         * @return Builder
         */
        public Builder setBottomItemTextColor(int color) {

            this.bottomItemTextColor = color;
            return this;
        }

        /**
         * 设置底部弹出对话框取消按钮文字大小
         *
         * @param size 大小
         * @return Builder
         */
        public Builder setBottomCancelTextSize(float size) {
            this.bottomCancelTextSize = PxUtils.fp2px(size);
            return this;
        }

        /**
         * 设置底部弹出对话框item文字大小
         *
         * @param size 大小
         * @return Builder
         */
        public Builder setBottomItemTextSize(float size) {
            this.bottomItemTextSize = PxUtils.fp2px(size);
            return this;
        }

        ////////////////////////////////////////输入框设置////////////////////////////////////////////

        /**
         * 设置输入框默认文字
         *
         * @param text 默认文字
         * @return Builder
         */
        public Builder setInputDefaultText(String text) {
            this.inputDefaultText = text;
            return this;
        }

        /**
         * 设置Hint文字
         *
         * @param text Hint 文字
         * @return Builder
         */
        public Builder setInputHintText(String text) {
            this.inputHintText = text;
            return this;
        }

        /**
         * 设置输入框文字颜色
         *
         * @param color 文字颜色
         * @return Builder
         */
        public Builder setInputTextColor(int color) {

            this.inputTextColor = new Color(context.getColor(color));
            return this;
        }

        /**
         * 设置输入框Hint文字颜色
         *
         * @param color Hint文字颜色
         * @return Builder
         */
        public Builder setInputHintTextColor(int color) {

            this.inputHintTextColor = color;
            return this;
        }

        /**
         * 设置输入框文字大小
         *
         * @param size 大小
         * @return Builder
         */
        public Builder setInputTextSize(float size) {
            this.inputTextSize = PxUtils.fp2px(size);
            return this;
        }

        /**
         * 设置输入框输入监听
         *
         * @param textWatcher 监听
         * @return Builder
         */
        public Builder setTextWatcher(Text.TextObserver textWatcher) {
            this.textWatcher = textWatcher;
            return this;
        }
        ////////////////////////////////////////其他设置////////////////////////////////////////////

        /**
         * 替换整个Dialog 内容
         *
         * @param view view
         * @return Builder
         */
        public Builder addAllDialogView(Component view) {
            this.allDialogView = view;
            this.type = DialogType.REPLACE_ALL;
            return this;
        }

        /**
         * 替换中间部分View
         *
         * @param view view
         * @return Builder
         */
        public Builder addContentView(Component view) {
            this.contentView = view;
            this.type = DialogType.REPLACE_CONTENT;
            return this;
        }

        /**
         * 替换底部弹出的View
         *
         * @param view view
         * @return Builder
         */
        public Builder setBottomView(Component view) {
            this.bottomView = view;
            this.type = DialogType.REPLACE_BOTTOM;
            return this;
        }

        /**
         * 是否可取消
         *
         * @param cancelable 可取消
         * @return Builder
         */
        public Builder setCancelable(boolean cancelable) {
            this.cancelable = cancelable;
            return this;
        }

        /**
         * 点击对话框周围是否可取消
         *
         * @param canceledOnTouchOutside 可取消
         * @return Builder
         */
        public Builder setCanceledOnTouchOutside(boolean canceledOnTouchOutside) {
            this.canceledOnTouchOutside = canceledOnTouchOutside;
            return this;
        }

        /**
         * 对话框消失监听
         *
         * @param dialogDismissListener 监听
         * @return Builder
         */
        public Builder setDialogDismissListener(CommonDialog.DestroyedListener dialogDismissListener) {
            this.dialogDismissListener = dialogDismissListener;
            return this;
        }

        /**
         * 创建对话框
         *
         * @return AppDialog
         */
        public AppDialog create() {
            return new AppDialog(this);
        }
    }
}
